class MetaNode {
  _nodePool = new Set();

  add(componentInstance) {
    return this._nodePool.add(componentInstance);
  }

}

class MetaComponents {

  _componentPool = {};

  set(componentInstance) {
    let componentTag = componentInstance.meta().tag();
    if (this.has(componentTag) === false) {
      this._componentPool[componentTag] = new MetaNode();
    }
    this._componentPool[componentTag].add(componentInstance);
    return this;
    // console.log(componentInstance.meta().tag());
    // console.log()
    // if (this.has(componentInstance) === false) {
    //   this._componentPool[componentInstance.tag()] = new MetaNode();
    // }
    // this._componentPool[componentInstance.tag()].add(componentInstance);
    // return this;
  }

  get(componentTag) {
    return this._componentPool[componentTag];
  }

  has(componentTag) {
    return this._componentPool.hasOwnProperty(componentTag);
  }
}


export class Meta {
  _componentInstance = null;
  _componentMetaComponents = new MetaComponents();

  componentInstance(componentInstance = null) {
    if (componentInstance == null) {
      return this._componentInstance;
    } else {
      this._componentInstance = componentInstance;
      return this;
    }
  }

  tag() {
    return this.componentInstance().$options._componentTag;
  }

  parents(filter = null) {
    let _parent = (parentSoruce) => {
      let parent = parentSoruce.$parent;
      if (filter !== null && filter.valid(parent) === false) {
        return _parent(parent);
      }
      // if (parent !== undefined) {
      //   return _parent(parent);
      // }
      return parent;
    }
    return _parent(this.componentInstance());
  }

  components() {
    return this._componentMetaComponents;
  }

}
